﻿using BCCommon;
using BCData.Sim.Admin.Admin;
using BCData.Sim.Admin.AdminPermissionRecord;
using BCData.Sim.Admin.StaffOrganizationMappingRecord;
using BCData.Sim.Company.Company;
using BCData.Sim.Company.Department;
using BCData.Sim.Company.Position;
using BCDto.Sim.Admin.Admin;
using BCDto.Sim.Company.Company;
using BCDto.Sim.Company.Department;
using BCEntity.Sim.Admin.Admin;
using BCEntity.Sim.Admin.StaffOrganizationMappingRecord;
using BCEntity.Sim.Company.Department;
using BCEntity.Sim.Company.Position;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.Sim.Company.Department
{
    public class DepartmentService : IDepartmentService
    {
        #region 私有变量
        private readonly IDatabaseContext databaseContext;
        private readonly IAdminData adminData;
        private readonly IDepartmentData departmentData;
        private readonly ICompanyData companyData;
        private readonly IStaffOrganizationMappingRecordData staffOrganizationMappingRecordData;
        private readonly IPositionData positionData;
        private readonly IRedisService redisService;
        private readonly IAdminPermissionRecordData adminPermissionRecordData;
        #endregion 私有变量

        public DepartmentService(IDatabaseContext databaseContext,
            IAdminData adminData,
            IDepartmentData departmentData,
            ICompanyData companyData,
            IStaffOrganizationMappingRecordData staffOrganizationMappingRecordData,
            IPositionData positionData,
            IRedisService redisService,
            IAdminPermissionRecordData adminPermissionRecordData)
        {
            this.databaseContext = databaseContext;
            this.adminData = adminData;
            this.departmentData = departmentData;
            this.companyData = companyData;
            this.staffOrganizationMappingRecordData = staffOrganizationMappingRecordData;
            this.positionData = positionData;
            this.redisService = redisService;
            this.adminPermissionRecordData = adminPermissionRecordData;
        }

        #region 公共方法
        #region 添加部门
        public DepartmentDto Add(AdminDto adminDto, DepartmentRequestDto dto)
        {
            //3、检查公司是否存在
            CheckCompanyExists(dto.CompanyId);

            string parentDepartmentName = string.Empty;
            //4、检查所属部门是否存在
            if (dto.ParentDepartmentId.HasValue)
            {
                parentDepartmentName = CheckParentDepartment(dto.ParentDepartmentId.Value).DepartmentName;
            }
            //5、检查部门名称是否存在
            CheckDepartmentNameExists(dto.CompanyId, dto.DepartmentName);

            var companyEntity = this.companyData.GetEntity(dto.CompanyId).GetAwaiter().GetResult();

            var departmentViewEntity = dto.As<DepartmentEntity>();
            departmentViewEntity.DepartmentPath = "0";
            departmentViewEntity.CompanyName = companyEntity.CompanyName;
            departmentViewEntity.CompanySubName = companyEntity.CompanySubName;
            departmentViewEntity.CompanyId = companyEntity.CompanyId;
            departmentViewEntity.EditerId = adminDto.AdminId;
            departmentViewEntity.Editer = adminDto.FullName;
            departmentViewEntity.ParentDepartmentName = parentDepartmentName;
            databaseContext.BeginTransaction();

            //8、创建部门
            var departmentEntity = departmentData.InsertAsync(departmentViewEntity).GetAwaiter().GetResult();
            if (departmentEntity == null)
            {
                throw new ArgumentException("添加部门失败!");
            }

            databaseContext.Commit();
            return departmentEntity.As<DepartmentDto>();
        }
        #endregion

        #region 修改部门
        public DepartmentDto Update(int id, AdminDto adminDto, DepartmentRequestDto dto)
        {
            //1、检查公司是否存在
            CheckCompanyExists(dto.CompanyId);

            //2.检查部门是否存在
            var departmentInfo = departmentData.GetById(id).GetAwaiter().GetResult();
            if (departmentInfo == null)
            {
                throw new ArgumentException("此部门不存在");
            }

            string departmentName = null;
            //5、检查所属部门是否存在
            if (dto.ParentDepartmentId.HasValue)
            {
                departmentName = CheckParentDepartment(dto.ParentDepartmentId.Value).DepartmentName;
            }

            var companyEntity = this.companyData.GetEntity(dto.CompanyId).GetAwaiter().GetResult();

            //6、修改
            var entity = dto.As<DepartmentEntity>();
            entity.DepartmentId = id;
            entity.CompanyName = companyEntity.CompanyName;
            entity.CompanySubName = companyEntity.CompanySubName;
            entity.CompanyId = companyEntity.CompanyId;
            entity.ParentDepartmentName = departmentName;
            entity.EditerId = adminDto.AdminId;
            entity.Editer = adminDto.FullName;
            databaseContext.BeginTransaction();
            var departmentResult = departmentData.UpdateAsync(entity).GetAwaiter().GetResult();
            if (departmentResult != null)
            {
                if (!this.companyData.UpdateInUsed(entity.CompanyId).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("修改部门信息失败!");
                }
            }
            if (departmentResult.ParentDepartmentId.HasValue)
            {
                if (!this.UpdateStaffCount(departmentResult.DepartmentId))
                {
                    throw new ArgumentException("更新部门员工人数失败!");
                }
                departmentResult = this.departmentData.GetById(departmentResult.DepartmentId).GetAwaiter().GetResult();
            }
            if (departmentInfo.ParentDepartmentId.HasValue || dto.ParentDepartmentId.HasValue)
            {
                if (departmentInfo.ParentDepartmentId != dto.ParentDepartmentId)
                {
                    this.adminPermissionRecordData.ClearDepartmentPermissionAsync(departmentResult.DepartmentId);
                }
            }
            databaseContext.Commit();
            return departmentResult.As<DepartmentDto>();
        }
        #endregion

        #region 删除部门
        public bool Delete(int departmentId)
        {
            var departmentEntity = this.departmentData.GetById(departmentId).Result;
            if (departmentEntity == null)
            {
                throw new ArgumentException("此部门信息不存在!");
            }
            if (this.departmentData.QueryChildren(departmentEntity.DepartmentId).Result.Any())
            {
                throw new ArgumentException("此部门存在下级部门，请先删除下级部门!");
            }
            var staffList = this.staffOrganizationMappingRecordData.GetDepartmentStaffList(departmentEntity.DepartmentId).Result;
            databaseContext.BeginTransaction();
            if (staffList.Any())
            {
                foreach (var staff in staffList)
                {
                    this.staffOrganizationMappingRecordData.Delete(staff.StaffOrganizationMappingRecordId).GetAwaiter().GetResult();
                }
            }
            var result = departmentData.DeleteAsync(departmentEntity.DepartmentId).GetAwaiter().GetResult();
            if (!result)
            {
                throw new ArgumentException("删除部门信息失败!");
            }
            if (departmentEntity.ParentDepartmentId.HasValue)
            {
                if (!this.UpdateStaffCount(departmentEntity.ParentDepartmentId.Value))
                {
                    throw new ArgumentException("重新计算部门人员数量失败!");
                }
            }
            var departmentList = this.departmentData.QueryRootDepartment(departmentEntity.CompanyId).GetAwaiter().GetResult();
            if (departmentList.Any())
            {
                this.companyData.UpdateInUsed(departmentEntity.CompanyId).GetAwaiter().GetResult();
            }
            else
            {
                this.companyData.UpdateUnused(departmentEntity.CompanyId).GetAwaiter().GetResult();
            }
            databaseContext.Commit();
            return result;
        }
        #endregion

        #region 获取部门信息
        public DepartmentDto Get(int departmentId)
        {
            var departmentInfo = departmentData.GetById(departmentId).GetAwaiter().GetResult();
            return departmentInfo.As<DepartmentDto>();
        }
        #endregion

        #region 获取部门分页数据
        public PageableList<DepartmentDto> Query(int companyId, string departmentName, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            var (data, count) = departmentData.Query(companyId, departmentName, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();

            return new PageableList<DepartmentDto>()
            {
                Count = count,
                Items = data.As<List<DepartmentDto>>(),
                PageIndex = pageIndex,
                PageSize = pageSize,
                ServerTime = DateTime.Now
            };
        }
        #endregion

        #region 获取公司根级部门列表
        public IEnumerable<DepartmentDto> Root(int companyId)
        {
            var result = this.departmentData.QueryRootDepartment(companyId).GetAwaiter().GetResult();
            return result.As<IEnumerable<DepartmentDto>>();
        }
        #endregion

        #region 获取部门子级部门列表
        public IEnumerable<DepartmentDto> Children(int departmentId)
        {
            var result = this.departmentData.QueryChildren(departmentId).GetAwaiter().GetResult();
            return result.As<IEnumerable<DepartmentDto>>();
        }

        public IEnumerable<DepartmentDto> Children(int departmentId, int companyId)
        {
            var task = departmentData.QueryChildren(departmentId, companyId);
            var entities = task.GetAwaiter().GetResult();
            return entities.As<IEnumerable<DepartmentDto>>();
        }
        #endregion

        #region 获取公司下所有部门信息列表
        public List<DepartmentDto> GetList(int companyId)
        {
            var data = departmentData.GetAll(companyId).GetAwaiter().GetResult();

            return data.As<List<DepartmentDto>>();
        }
        #endregion

        #region 获取部门人员列表
        public List<DepartmentPrincipalDto> StaffList(int companyId, int? departmentId)
        {
            var data = departmentData.GetStaffList(companyId, departmentId).GetAwaiter().GetResult();
            return data.As<List<DepartmentPrincipalDto>>();
        }
        #endregion

        #region 获取部门子级树列表
        public List<object> ChildrenTree(int companyId, int? departmentId)
        {
            List<object> result = new List<object>();
            if (!departmentId.HasValue)
            {
                var list = this.Root(companyId);
                foreach (var item in list)
                {
                    result.Add(GetDepartmentTree(item.DepartmentId));
                }
            }
            else
            {
                result.Add(GetDepartmentTree(departmentId.Value));
            }
            return result;
        }
        #endregion

        #region 获取公司、部门及所有子级部门树型列表
        public List<object> CompanyDepartmentPersonTree(string levelType, bool selectable,bool allowAcrossCompany, int companyId)
        {
            string cacheKey = this.redisService.GetKey("CompanyDepartmentPersonTree", levelType, selectable, allowAcrossCompany, companyId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                List<CompanyDto> companyDtos = this.companyData.GetList().GetAwaiter().GetResult().As<List<CompanyDto>>();
                if (allowAcrossCompany)
                {
                    List<object> resultTree = GetCompanyTree(companyDtos, levelType, selectable);
                    return resultTree;
                }
                else
                {
                    var company = companyDtos.Where(p => p.CompanyId == companyId);
                    List<object> resultTree = GetCompanyTree(company, levelType, selectable);
                    return resultTree;
                }
            }, TimeSpan.FromDays(1));
            return result;
        }

        public List<object> CompanyDepartmentPersonTree(string levelType, bool selectable, int companyId,int departmentId)
        {
            string cacheKey = this.redisService.GetKey("SingleCompanyDepartmentPersonTree", levelType, selectable, companyId, departmentId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                CompanyDto company = this.companyData.GetEntity(companyId).GetAwaiter().GetResult().As<CompanyDto>();
                List<object> resultTree = new List<object>();
                object companyObj = new
                {
                    Title = company.CompanyName,
                    Key = string.Format("{0}-{1}", levelType, company.CompanyId),
                    Selectable = selectable,
                    Origin = company,
                    isLeaf = true,
                    Children = new List<object> { GetDepartmentTree(departmentId, levelType, selectable) }
                };
                resultTree.Add(companyObj);
                return resultTree;
            }, TimeSpan.FromDays(1));
            return result;
        }
        #endregion

        #region 设置部门负责人信息
        public bool SetPrincipalInfo(DepartmentPrincipalPutDto departmentPrincipalPutDto)
        {
            var entity = this.departmentData.GetById(departmentPrincipalPutDto.DepartmentId).GetAwaiter().GetResult();
            if (entity == null)
            {
                throw new ArgumentException("此部门不存在!");
            }
            var adminEntity = this.adminData.GetAdmin(departmentPrincipalPutDto.AdminId).GetAwaiter().GetResult();
            if (adminEntity == null)
            {
                throw new ArgumentException("此人员不存在或已被停用!");
            }
            this.databaseContext.BeginTransaction();

            var result = this.departmentData.UpdateDepartmentPrincipal(entity.CompanyId, entity.DepartmentId, adminEntity.AdminId, adminEntity.FullName).GetAwaiter().GetResult();
            if (!result)
            {
                throw new ArgumentException("设置部门负责人信息失败!");
            }

            if (!this.staffOrganizationMappingRecordData.Exists(entity.CompanyId, entity.DepartmentId, adminEntity.AdminId).GetAwaiter().GetResult())
            {
                if (this.staffOrganizationMappingRecordData.Exists(entity.DepartmentPath, adminEntity.AdminId).GetAwaiter().GetResult())
                {
                    int oldDepartmentId = 0;
                    var staffMapping = this.staffOrganizationMappingRecordData.GetEntity(entity.DepartmentPath, adminEntity.AdminId).GetAwaiter().GetResult();
                    oldDepartmentId = staffMapping.DepartmentId;
                    staffMapping.DepartmentId = entity.DepartmentId;
                    staffMapping.DepartmentName = entity.DepartmentName;
                    staffMapping.JobDuty = adminEntity.JobDuty;
                    staffMapping.JobTitle = adminEntity.JobTitle;
                    staffMapping.JobDutyKey = adminEntity.JobDutyKey;
                    staffMapping.JobTitleKey = adminEntity.JobTitleKey;
                    var staffResult = this.staffOrganizationMappingRecordData.Update(staffMapping).GetAwaiter().GetResult();
                    if (staffResult == null)
                    {
                        throw new ArgumentException("设置部门负责人映射信息失败!");
                    }
                    var oldDepartment = this.departmentData.GetById(oldDepartmentId).GetAwaiter().GetResult();
                    if(oldDepartment.PrincipalAdminId== adminEntity.AdminId)
                    {
                        var oldDepartmentResult = this.departmentData.RemovePrincipalInfo(oldDepartment.CompanyId, oldDepartment.DepartmentId).GetAwaiter().GetResult();
                        if (oldDepartmentResult == null)
                        {
                            throw new ArgumentException("更新部门负责人原所在部门信息!");
                        }
                    }
                    if (!this.UpdateStaffCount(oldDepartmentId))
                    {
                        throw new ArgumentException("更新部门员工人数失败!");
                    }
                }
                else
                {
                    var staffEntity = new StaffOrganizationMappingRecordEntity();
                    staffEntity.CompanyId = entity.CompanyId;
                    staffEntity.CompanyName = entity.CompanyName;
                    staffEntity.DepartmentId = entity.DepartmentId;
                    staffEntity.DepartmentName = entity.DepartmentName;
                    staffEntity.JobDuty = adminEntity.JobDuty;
                    staffEntity.JobTitle = adminEntity.JobTitle;
                    staffEntity.JobDutyKey = adminEntity.JobDutyKey;
                    staffEntity.JobTitleKey = adminEntity.JobTitleKey;
                    staffEntity.AdminId = adminEntity.AdminId;
                    staffEntity.FullName = adminEntity.FullName;
                    var staffResult = this.staffOrganizationMappingRecordData.Add(staffEntity).GetAwaiter().GetResult();
                    if (staffResult == null)
                    {
                        throw new ArgumentException("设置部门负责人映射信息失败!");
                    }
                }
            }
            if (!this.UpdateStaffCount(entity.DepartmentId))
            {
                throw new ArgumentException("更新部门员工人数失败!");
            }
            this.databaseContext.Commit();
            return result;
        }
        #endregion

        #region 移除部门负责人信息
        public bool RemovePrincipalInfo(AdminDto adminDto, DepartmentPrincipalPutDto departmentPrincipalPutDto)
        {
            var entity = this.departmentData.GetById(departmentPrincipalPutDto.DepartmentId).GetAwaiter().GetResult();
            if (entity == null)
            {
                throw new ArgumentException("此部门不存在");
            }
            if (adminDto.CompanyId != departmentPrincipalPutDto.CompanyId)
            {
                if (!adminDto.IsSystemAccount)
                {
                    throw new ArgumentException("您无权操作其他公司部门");
                }
            }
            return this.departmentData.RemovePrincipalInfo(entity.CompanyId, entity.DepartmentId).GetAwaiter().GetResult() != null;
        }
        #endregion

        #region 更新员工数量
        public bool UpdateStaffCount(int departmentId)
        {
            var departmentEntity = this.departmentData.GetById(departmentId).Result;
            string[] path = departmentEntity.DepartmentPath.IndexOf(",") > -1 ? departmentEntity.DepartmentPath.Split(',') : new string[] { departmentEntity.DepartmentPath };
            int i = 0;
            foreach (string item in path)
            {
                if (i > 0)
                {
                    int id = Convert.ToInt32(item);
                    if (id > 0)
                    {
                        this.departmentData.UpdateStaffCountAsync(id).GetAwaiter().GetResult();
                    }
                }
                i++;
            }
            return this.departmentData.UpdateStaffCountAsync(departmentId).GetAwaiter().GetResult();
        }
        #endregion
        #endregion 公共方法

        #region 私有方法
        /// <summary>
        /// 获取公司、部门及所有子级部门树型列表
        /// </summary>
        /// <param name="companyDtos">公司列表</param>
        /// <param name="levelType">级别类型</param>
        /// <param name="selectable">允许选中</param>
        /// <returns></returns>
        private List<object> GetCompanyTree(IEnumerable<CompanyDto> companyDtos, string levelType, bool selectable)
        {
            List<object> resultTree = new List<object>();
            foreach (var company in companyDtos)
            {
                if (levelType == "Company")
                {
                    object companyObj = new
                    {
                        Title = company.CompanyName,
                        Key = string.Format("{0}-{1}", levelType, company.CompanyId),
                        Selectable = selectable,
                        Origin = company,
                        isLeaf = true
                    };
                    resultTree.Add(companyObj);
                }
                else
                {
                    var list = this.Root(company.CompanyId);
                    List<object> departmentList = new List<object>();
                    foreach (var item in list)
                    {
                        var department = GetDepartmentTree(item.DepartmentId, levelType, selectable);
                        if (department != null)
                        {
                            departmentList.Add(department);
                        }
                    }
                    object companyObj = new
                    {
                        Title = company.CompanyName,
                        Key = string.Format("{0}-{1}", levelType, company.CompanyId),
                        DisableCheckbox = true,
                        Origin = company,
                        Selectable = !selectable,
                        Children = departmentList.ToArray()
                    };
                    resultTree.Add(companyObj);
                }
            }
            return resultTree;
        }

        /// <summary>
        /// 获取部门树型
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <returns></returns>
        private object GetDepartmentTree(int departmentId)
        {
            var departmentInfo = this.departmentData.GetById(departmentId).GetAwaiter().GetResult();
            if (departmentInfo == null)
            {
                throw new ArgumentException("此部门不存在");
            }
            var childrenList = this.GetChildrenTree(departmentId);
            if (childrenList.Any())
            {
                object child = new
                {
                    //Title = departmentInfo.DepartmentName,
                    Title = string.Format("{0}-{1}", departmentInfo.DepartmentName, departmentInfo.DepartmentPrincipal),
                    Key = string.Format("{0}-{1}-{2}", departmentInfo.CompanyId, departmentInfo.DepartmentId, departmentInfo.PrincipalAdminId),
                    Origin = departmentInfo,
                    Children = childrenList.ToArray()
                };
                return child;
            }
            else
            {
                object child = new
                {
                    //Title = departmentInfo.DepartmentName,
                    Title = string.Format("{0}-{1}", departmentInfo.DepartmentName, departmentInfo.DepartmentPrincipal),
                    Key = string.Format("{0}-{1}-{2}", departmentInfo.CompanyId, departmentInfo.DepartmentId, departmentInfo.PrincipalAdminId),
                    Origin = departmentInfo
                };
                return child;
            }
        }
        /// <summary>
        /// 获取部门树型
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <param name="levelType">级别类型</param>
        /// <param name="selectable">允许选中</param>
        /// <returns></returns>
        private object GetDepartmentTree(int departmentId, string levelType, bool selectable)
        {
            var departmentInfo = this.departmentData.GetById(departmentId).GetAwaiter().GetResult();
            if (departmentInfo == null)
            {
                return null;
            }
            var childrenList = this.GetChildrenTree(departmentId, levelType, selectable);
            if (childrenList.Any())
            {
                if (levelType == "Position")
                {
                    var personList = GetChildrenPositionTree(departmentInfo.CompanyId, departmentInfo.DepartmentId, selectable);
                    childrenList.AddRange(personList);
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        Origin = departmentInfo,
                        DisableCheckbox = true,
                        Selectable = !selectable,
                        Children = childrenList.ToArray()
                    };
                    return child;
                }
                else if (levelType == "Human")
                {
                    var personList = GetPersonTree(departmentInfo.DepartmentId, selectable);
                    List<object> departmentList = childrenList.ToList();
                    departmentList.AddRange(personList);
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        DisableCheckbox = true,
                        Origin = departmentInfo,
                        Selectable = !selectable,
                        Children = departmentList.ToArray()
                    };
                    return child;
                }
                else
                {
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        Origin = departmentInfo,

                        Children = childrenList.ToArray(),
                        Selectable = selectable
                    };
                    return child;
                }
            }
            else
            {
                if (levelType == "Department")
                {
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        Origin = departmentInfo,
                        isLeaf = true,
                        Selectable = selectable
                    };
                    return child;
                }
                else if (levelType == "Position")
                {
                    var personList = GetChildrenPositionTree(departmentInfo.CompanyId, departmentInfo.DepartmentId, selectable);
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        Origin = departmentInfo,
                        DisableCheckbox = true,
                        Selectable = !selectable,
                        Children = personList.ToArray()
                    };
                    return child;
                }
                else
                {
                    var personList = GetPersonTree(departmentInfo.DepartmentId, selectable);
                    object child = new
                    {
                        Title = departmentInfo.DepartmentName,
                        Key = string.Format("{0}-{1}-{2}", levelType, departmentInfo.CompanyId, departmentInfo.DepartmentId),
                        Origin = departmentInfo,
                        DisableCheckbox = true,
                        Selectable = !selectable,
                        Children = personList.ToArray()
                    };
                    return child;
                }
            }
        }
        /// <summary>
        /// 获取部门子级树列表
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <returns></returns>
        private List<object> GetChildrenTree(int departmentId)
        {
            List<object> result = new List<object>();
            var list = this.departmentData.QueryChildren(departmentId).GetAwaiter().GetResult();
            foreach (var item in list)
            {
                var childrenList = GetChildrenTree(item.DepartmentId);
                if (childrenList.Any())
                {
                    object child = new
                    {
                        //Title = item.DepartmentName,
                        Title = string.Format("{0}-{1}", item.DepartmentName, item.DepartmentPrincipal),
                        Key = string.Format("{0}-{1}-{2}", item.CompanyId, item.DepartmentId, item.PrincipalAdminId),
                        Origin = item,
                        Children = childrenList.ToArray()
                    };
                    result.Add(child);
                }
                else
                {
                    object child = new
                    {
                        //Title = item.DepartmentName,
                        Title = string.Format("{0}-{1}", item.DepartmentName, item.DepartmentPrincipal),
                        Key = string.Format("{0}-{1}-{2}", item.CompanyId, item.DepartmentId, item.PrincipalAdminId),
                        Origin = item
                    };
                    result.Add(child);
                }
            }
            return result;
        }
        /// <summary>
        /// 获取部门子级树列表
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <param name="levelType">级别类型</param>
        /// <param name="selectable">允许选中</param>
        /// <returns></returns>
        private List<object> GetChildrenTree(int departmentId, string levelType, bool selectable)
        {
            List<object> result = new List<object>();
            var list = this.departmentData.QueryChildren(departmentId).GetAwaiter().GetResult();
            foreach (var item in list)
            {
                var childrenList = GetChildrenTree(item.DepartmentId, levelType, selectable);
                if (childrenList.Any())
                {
                    if (levelType == "Position")
                    {
                        var personList = GetChildrenPositionTree(item.CompanyId, item.DepartmentId, selectable);
                        childrenList.AddRange(personList);
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            DisableCheckbox = true,
                            Origin = item,
                            Selectable = !selectable,
                            Children = childrenList.ToArray()
                        };
                        result.Add(child);
                    }
                    else if (levelType == "Human")
                    {
                        var personList = GetPersonTree(item.DepartmentId, selectable);
                        List<object> departmentList = childrenList.ToList();
                        departmentList.AddRange(personList);
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            DisableCheckbox = true,
                            Origin = item,
                            Selectable = !selectable,
                            Children = departmentList.ToArray()
                        };
                        result.Add(child);
                    }
                    else
                    {
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            Origin = item,
                            Selectable = selectable,
                            Children = childrenList.ToArray()
                        };
                        result.Add(child);
                    }
                }
                else
                {
                    if (levelType == "Department")
                    {
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            Origin = item,
                            Selectable = selectable,
                            isLeaf = true
                        };
                        result.Add(child);
                    }
                    else if (levelType == "Position")
                    {
                        var personList = GetChildrenPositionTree(item.CompanyId, item.DepartmentId, selectable);
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            Origin = item,
                            DisableCheckbox = true,
                            Selectable = !selectable,
                            Children = personList.ToArray()
                        };
                        result.Add(child);
                    }
                    else
                    {
                        var personList = GetPersonTree(item.DepartmentId, selectable);
                        object child = new
                        {
                            Title = item.DepartmentName,
                            Key = string.Format("{0}-{1}-{2}", levelType, item.CompanyId, item.DepartmentId),
                            Origin = item,
                            DisableCheckbox = true,
                            Selectable = !selectable,
                            Children = personList.ToArray()
                        };
                        result.Add(child);
                    }
                }
            }
            return result;
        }
        private List<object> GetChildrenPositionTree(int companyId, int departmentId, bool selectable)
        {
            IEnumerable<PositionEntity> positionEntities = this.positionData.GetList(companyId, departmentId, true).GetAwaiter().GetResult();
            List<object> resultTree = GetCompanyPositionTree(positionEntities, selectable);
            return resultTree;
        }
        private List<object> GetCompanyPositionTree(IEnumerable<PositionEntity> positionEntities, bool selectable)
        {
            List<object> resultTree = new List<object>();
            foreach (var item in positionEntities.Where(p => !p.ParentPositionId.HasValue))
            {
                var children = GetChildrenPositionTree(positionEntities, item.PositionId, selectable);
                if (children.Any())
                {
                    object child = new
                    {
                        Title = item.PositionName,
                        Key = string.Format("{0}-{1}-{2}-{3}", "Position", item.CompanyId, item.DepartmentId, item.PositionId),
                        Origin = item,
                        Selectable = selectable,
                        Children = children.ToArray()
                    };
                    resultTree.Add(child);
                }
                else
                {
                    object child = new
                    {
                        Title = item.PositionName,
                        Key = string.Format("{0}-{1}-{2}-{3}", "Position", item.CompanyId, item.DepartmentId, item.PositionId),
                        Origin = item,
                        Selectable = selectable,
                        isLeaf = true
                    };
                    resultTree.Add(child);
                }
            }
            return resultTree;
        }
        private List<object> GetChildrenPositionTree(IEnumerable<PositionEntity> positionEntities, int parentPositionId, bool selectable)
        {
            List<object> resultTree = new List<object>();
            var list = positionEntities.Where(p => p.ParentPositionId == parentPositionId);
            if (list.Any())
            {
                foreach (var item in list)
                {
                    var children = GetChildrenPositionTree(positionEntities, item.PositionId, selectable);
                    if (children.Any())
                    {
                        object child = new
                        {
                            Title = item.PositionName,
                            Key = string.Format("{0}-{1}-{2}-{3}", "Position", item.CompanyId, item.DepartmentId, item.PositionId),
                            Origin = item,
                            Selectable = selectable,
                            Children = children.ToArray()
                        };
                        resultTree.Add(child);
                    }
                    else
                    {
                        object child = new
                        {
                            Title = item.PositionName,
                            Key = string.Format("{0}-{1}-{2}-{3}", "Position", item.CompanyId, item.DepartmentId, item.PositionId),
                            Origin = item,
                            Selectable = selectable,
                            isLeaf = true
                        };
                        resultTree.Add(child);
                    }
                }
            }
            return resultTree;
        }
        /// <summary>
        /// 获取人员树列表
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <param name="selectable">允许选中</param>
        /// <returns></returns>
        private List<object> GetPersonTree(int departmentId, bool selectable)
        {
            List<object> result = new List<object>();
            var list = this.staffOrganizationMappingRecordData.GetCurrentlyDepartmentStaffList(departmentId).GetAwaiter().GetResult();
            foreach (var item in list)
            {
                object child = new
                {
                    Title = item.FullName,
                    Key = string.Format("{0}-{1}-{2}-{3}", "Human", item.CompanyId, item.DepartmentId, item.AdminId),
                    Origin = item,
                    Selectable = selectable,
                    isLeaf = true
                };
                result.Add(child);
            }
            return result;
        }
        /// <summary>
        /// 获取部门下岗位树列表
        /// </summary>
        /// <param name="departmentId">部门Id</param>
        /// <param name="selectable">允许选中</param>
        /// <returns></returns>
        private List<object> GetPositionTree(int departmentId, bool selectable)
        {
            List<object> result = new List<object>();
            return result;
        }
        /// <summary>
        /// 检查部门负责人是否存在
        /// </summary>
        /// <param name="principalAdmin">部门负责人id</param>
        private AdminEntity CheckPrincipalAdminExist(long principalAdmin)
        {
            var adminEntity = adminData.GetAdmin(principalAdmin).GetAwaiter().GetResult();
            if (adminEntity == null)
                throw new ArgumentException("部门负责人不存在");
            else
                return adminEntity;
        }
        /// <summary>
        /// 检查公司是否存在
        /// </summary>
        /// <param name="companyId">公司Id</param>
        /// <returns></returns>
        private void CheckCompanyExists(int companyId)
        {
            if (!this.companyData.CheckCompanyExists(companyId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此公司不存在");
            }
        }

        /// <summary>
        /// 检查部门名称是否已存在
        /// </summary>
        /// <param name="companyId">公司Id</param>
        /// <param name="departmentName">部门名称</param>
        /// <returns></returns>
        private void CheckDepartmentNameExists(int companyId, string departmentName)
        {
            var depatmentList = departmentData.CheckDepartmentName(companyId, departmentName).Result;
            if (depatmentList != null)
                throw new ArgumentException("部门已存在");
        }

        /// <summary>
        /// 检查所属部门是否存在
        /// </summary>
        /// <param name="parentDepartmentId">所属部门id</param>
        /// <returns></returns>
        private DepartmentEntity CheckParentDepartment(int parentDepartmentId)
        {
            var parentDepartment = departmentData.GetById(parentDepartmentId).Result;
            if (parentDepartment == null)
            {
                throw new ArgumentException("所属部门不存在");
            }
            return parentDepartment;
        }

        #endregion 私有方法


    }
}
